package com.tc.picturesynthesis.first.util;

import com.tc.picturesynthesis.first.domain.UserInfo;

import net.coobird.thumbnailator.Thumbnails;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import javax.imageio.ImageIO;
import java.awt.*;
import java.awt.geom.Ellipse2D;
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.IOException;
import java.net.URL;
import java.util.Arrays;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * 图片合成工具类
 *
 * @author tc
 * @date 2024/04/12
 */

public class PicSynthesisUtil {

    /**
     * 默认二维码识别跳转界面
     */
    public static final String DEFAULT_BDVIEW = "http://xxx.com/xxx?id=";
    public static final double DOUBLE_TO_INT_QR = 0.33;
    /**
     * 测试头像
     */
    public static String Head_Test = "https://game-1256953255.cos.ap-guangzhou.myqcloud.com/myPictrue/head.jpg";


    private static final Logger log = LoggerFactory.getLogger(PicSynthesisUtil.class);

    private Font font = new Font("微软雅黑", Font.BOLD, 70);// 添加字体的属性设置

    private Graphics2D g = null;
    private int fontsize = 0;
    private int x = 0;
    private int y = 0;

    /**
     * 主文件夹
     */
    private static final String baseUrl = "D:/pic/";
    /**
     * 默认生成图片的地址
     */
    private static final String success = "success/";
    /**
     * 默认生成二维码图片保存地址
     */
    public static final String DEFAULT_IMG_BASEURL = baseUrl + "qrBD/BD/";

    /**
     * jpg格式
     */
    private static final String jpg = ".jpg";
    /**
     * 图片背景
     */
    private static final String beijing = "https://game-1256953255.cos.ap-guangzhou.myqcloud.com/myPictrue/yaoqingbeijing128.png";
    /**
     * 底边
     */
    private static final String dibian = "https://game-1256953255.cos.ap-guangzhou.myqcloud.com/myPictrue/yaoqingdibian128.png";


    public static final double DOUBLE_TO_INT_HEAD = 0.35;



    public void initImage(UserInfo user) throws IOException {
        //检查所需路径是否存在,不存在的话创建文件夹
        checkPath();

        Map<String, String> map = new HashMap<String, String>();
        //底边背景合成路径
        String newPicUrl = new StringBuffer(baseUrl).append(success).append(user.getUserId()).append(jpg).toString();
        //文件不存在的话
        if (!new File(newPicUrl).exists()) {
            //生成用户的邀请二维码
            Map<String, String> qrCodeMap = QrCodeUtil.getUserQrImgURL(user);
            if (qrCodeMap != null) {
                String qrCodeImgURL = qrCodeMap.get("qrPath");
                String qrCode = qrCodeMap.get("qrCode");
                boolean isOk = true;
                try {
                    BufferedImage head_ = this.getBufferedImageForURL(user.getHeadImgUrl());
                    BufferedImage qrCodeImg = this.getBufferedImageForLocal(qrCodeImgURL);
                    BufferedImage beijing_ = this.getBufferedImageForURL(beijing);
                    BufferedImage dibian_ = this.getBufferedImageForURL(dibian);

                    //合成底边
                    head_ = this.convertCircular(head_);
                    head_ = this.scaleByPercentage(head_, this.doubleToInt(dibian_, DOUBLE_TO_INT_HEAD), doubleToInt(dibian_, DOUBLE_TO_INT_HEAD), beijing_);
                    isOk = this.writeImageLocal(new StringBuilder(baseUrl).append("head.jpg").toString(), head_);

                    //合成头像
                    int x = 30;
                    int y = 75;
                    int weight1 = head_.getWidth();
                    int height1 = head_.getHeight();
                    this.modifyImagetogeter(head_, dibian_, x, y, height1, weight1);
                    isOk = this.writeImageLocal(new StringBuilder(baseUrl).append("dibian.jpg").toString(), this.modifyImagetogeter(head_, dibian_, x, y, height1, weight1));

                    //添加文字
                    x = 100;
                    y = 135;
                    this.modifyImage(dibian_, getCode(user.getInviteCode()), x, y);
                    isOk = this.writeImageLocal(new StringBuilder(baseUrl).append("xiabufen1.jpg").toString(), this.modifyImage(dibian_, getCode(user.getInviteCode()), x, y));


                    //合成二维码
                    x = 325;
                    y = 12;
                    int weight3 = doubleToInt(qrCodeImg, DOUBLE_TO_INT_QR);
                    int height3 = doubleToInt(qrCodeImg, DOUBLE_TO_INT_QR);
                    this.modifyImagetogeter(qrCodeImg, dibian_, x, y, doubleToInt(qrCodeImg, DOUBLE_TO_INT_QR), doubleToInt(qrCodeImg, DOUBLE_TO_INT_QR));
                    isOk = this.writeImageLocal(new StringBuilder(baseUrl).append("xiabufen2.jpg").toString(), this.modifyImagetogeter(qrCodeImg, dibian_, x, y, height3, weight3));


                    x = 0;
                    y = beijing_.getHeight() - dibian_.getHeight();
                    int weight = dibian_.getWidth();
                    int height = dibian_.getHeight();
                    isOk = this.writeImageLocal(newPicUrl, this.modifyImagetogeter(dibian_, beijing_, x, y, height, weight));

                } catch (Exception e) {
                    log.error("合成异常" + e.getMessage());
                }

                if (!isOk) {
                    log.error("生成图片失败!");
                }
                log.info("生成图片成功!");

                map.put("qrCode", qrCode);
                map.put("newPicUrl", newPicUrl);

            }

        } else {
            log.info("图片已存在!");

            map.put("qrCode", new StringBuffer(DEFAULT_IMG_BASEURL).append(user.getUserId()).toString());
            map.put("newPicUrl", newPicUrl);
        }
        log.info("邀请链接:{},图片地址:{}",map.get("qrCode"),map.get("newPicUrl"));


    }

    /**
     * 检查路径
     */
    private void checkPath() {
        //保存文件的路径
        File directory1 = new File(baseUrl + success);
        File directory2 = new File(DEFAULT_IMG_BASEURL);
        List<File> files = Arrays.asList(directory1, directory2);

        for (File directory : files) {
            // 创建目录
            if (!directory.exists()) {
                if (directory.mkdirs()) {
                    System.out.println("目录已创建");
                } else {
                    System.out.println("无法创建目录");
                }
            }
        }

    }

    /**
     * 网络图片输出到BufferedImage
     *
     * @throws IOException
     */
    private BufferedImage getBufferedImageForURL(String filePath) throws IOException {
        //asBufferedImage() 返回BufferedImage
        return Thumbnails.of(new URL(filePath)).scale(1).asBufferedImage();
    }


    /**
     * 本地图片输出到BufferedImage
     *
     * @throws IOException
     */
    private BufferedImage getBufferedImageForLocal(String filePath) throws IOException {
        /**
         * asBufferedImage() 返回BufferedImage
         */
        return Thumbnails.of(filePath).scale(1).asBufferedImage();
    }


    /**
     * 传入的图像必须是正方形的 才会 圆形 如果是长方形的比例则会变成椭圆的
     *
     * @param bi1 图片
     * @return
     * @throws IOException
     */
    public BufferedImage convertCircular(BufferedImage bi1) throws IOException {
        // 透明底的图片
        BufferedImage bi2 = new BufferedImage(bi1.getWidth(), bi1.getHeight(), BufferedImage.TYPE_4BYTE_ABGR);
        Ellipse2D.Double shape = new Ellipse2D.Double(0, 0, bi1.getWidth(), bi1.getHeight());
        Graphics2D g2 = bi2.createGraphics();
        g2.setClip(shape);
        // 使用 setRenderingHint 设置抗锯齿
        g2.drawImage(bi1, 0, 0, null);
        // 设置颜色
        g2.setBackground(Color.green);
        g2.dispose();
        return bi2;
    }

    /**
     * 缩小Image，此方法返回源图像按给定宽度、高度限制下缩放后的图像
     *
     * @param inputImage
     * @param newWidth：压缩后宽度
     * @param newHeight：压缩后高度
     * @param beijing：背景图片
     * @throws IOException
     */
    public BufferedImage scaleByPercentage(BufferedImage inputImage, int newWidth, int newHeight, BufferedImage beijing) throws Exception {
        // 获取原始图像透明度类型
        int type = inputImage.getColorModel().getTransparency();
        int width = inputImage.getWidth();
        int height = inputImage.getHeight();
        // 开启抗锯齿
        RenderingHints renderingHints = new RenderingHints(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
        // 使用高质量压缩
        renderingHints.put(RenderingHints.KEY_RENDERING, RenderingHints.VALUE_RENDER_QUALITY);
        BufferedImage img = new BufferedImage(newWidth, newHeight, type);
        Graphics2D graphics2d = img.createGraphics();
        graphics2d.setRenderingHints(renderingHints);
        graphics2d.drawImage(inputImage, 0, 0, newWidth, newHeight, 0, 0, width, height, null);
        graphics2d.dispose();
        return img;
    }


    /**
     * 生成新图片到本地
     */
    public boolean writeImageLocal(String newImage, BufferedImage img) {
        boolean isok = false;
        if (newImage != null && img != null) {
            try {
                File outputfile = new File(newImage);
                isok = ImageIO.write(img, "jpg", outputfile);
            } catch (IOException e) {
                System.out.println(e.getMessage());
            }
        }
        return isok;
    }


    /**
     * 头像缩放 四舍五入  double转int
     *
     * @param beijing_
     * @return
     */
    public Integer doubleToInt(BufferedImage beijing_, double d) {
        return (new Double((d * beijing_.getHeight()))).intValue();
    }


    /**
     * 合成图片
     *
     * @param b      图片b
     * @param d      图片d
     * @param x      x坐标
     * @param y      y坐标
     * @param height 高度
     * @param weight 宽度
     * @return
     */
    public BufferedImage modifyImagetogeter(BufferedImage b, BufferedImage d, int x, int y, int height, int weight) {
        try {
            g = d.createGraphics();
            g.drawImage(b, x, y, weight, height, null);
            g.dispose();
        } catch (Exception e) {
            System.out.println(e.getMessage());
        }
        return d;
    }


    /**
     * 修改图片,返回修改后的图片缓冲区（只输出一行文本）
     */
    public BufferedImage modifyImage(BufferedImage img, Object content, int x, int y) {
        try {
            int w = img.getWidth();
            int h = img.getHeight();
            g = img.createGraphics();
            g.setBackground(Color.WHITE);
            g.setColor(Color.BLACK);//设置字体颜色
            if (this.font != null) {
                g.setFont(this.font);
            }
            // 验证输出位置的纵坐标和横坐标
            if (x >= h || y >= w) {
                this.x = h - this.fontsize + 2;
                this.y = w;
            } else {
                this.x = x;
                this.y = y;
            }
            g.setFont(new Font("微软雅黑", Font.BOLD, 22));
            if (content != null) {
                g.drawString(content.toString(), this.x, this.y);
            }
            g.setBackground(Color.WHITE);
            g.dispose();
        } catch (Exception e) {
            System.out.println(e.getMessage());
        }
        return img;
    }


    /**
     * 让字符串隔开展现
     *
     * @param code
     * @return
     */
    public static String getCode(String code) {
        StringBuilder sb = new StringBuilder();
        for (int i = 0; i < code.length(); i++) {
            if (i != (code.length() - 1)) {
                sb.append(code.charAt(i)).append(" ");
            } else {
                sb.append(code.charAt(i));
            }
        }
        return sb.toString();
    }

}
